package com.hardware.mrd;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;


import com.my.service.MyCmd;
import com.my.service.ICallback;
import com.my.service.IMyService;

public class AkRadio {
	static {
		System.loadLibrary("Radio");
	}

	public AkRadio() {
		if(isRds()){
			mFreqListSize = 6;
		}
	}

	private static final String TAG = "AkRadio";
	
	public static final int MSC_TUNER = 0x0;
	public static final int MSC_TUNER_OFF = 0x1;

	private native final int nativeSendMSCCommand(int value);

	public int sendMSCCommand(int value) {
		int ret = -1;
		if (mIMYService != null) {
			try {
				switch (value) {
				case MSC_TUNER:
					ret = mIMYService.setSource(MyCmd.SOURCE_RADIO, MyCmd.SOURCE_RADIO);
					break;
				case MSC_TUNER_OFF:
					ret = mIMYService.setSource(MyCmd.SOURCE_RADIO, MyCmd.SOURCE_AV_OFF);
					break;
				default:
					break;
				}
			} catch (RemoteException e) {
				Log.e(TAG, e.toString());
			}
		}
		return ret;
	}
	
	public static final int MRD_READ = 0x0;
	public static final int MRD_READ_BAND = 0x1;
	public static final int MRD_READ_NAMBER = 0x2;
	public static final int MRD_READ_FREQENCY = 0x3;
	public static final int MRD_READ_STRENGTH = 0x4;
	public static final int MRD_READ_FLAG = 0x5;
	public static final int MRD_READ_FREQS = 0x6;
	public static final int MRD_READ_REGION = 0x7;
	public static final int MRD_READ_PARAM = 0x8;
	public static final int MRD_WRITE_BAND = 0x10;
	public static final int MRD_AS = 0x11;
	public static final int MRD_PS = 0x12;
	public static final int MRD_SCAN = 0x13;
	public static final int MRD_SEEK_UP = 0x14;
	public static final int MRD_SEEK_DOWN = 0x15;
	public static final int MRD_STEP_UP = 0x16;
	public static final int MRD_STEP_DOWN = 0x17;
	public static final int MRD_SCAN_STOP = 0x18;
	public static final int MRD_WRITE_LOCDX = 0x19;
	public static final int MRD_PLAY = 0x1a;
	public static final int MRD_SAVE = 0x1b;
	public static final int MRD_WRITE_REGION = 0x1c;
	public static final int MRD_WRITE_FREQENCY = 0x1d;
	public static final int MRD_WRITE_PARAM = 0x1e;
	public static final int MRD_INFO = 0x1f;

	public static final int MRD_READ_RDS = 0x20;
	public static final int MRD_READ_RDS_FLAG = 0x21;
	public static final int MRD_READ_RDS_PTY = 0x22;
	public static final int MRD_READ_RDS_PS = 0x23;
	public static final int MRD_READ_RDS_RT = 0x24;
	public static final int MRD_READ_RDS_PSLIST = 0x25;
	public static final int MRD_RDS_AF_OFF = 0x30;
	public static final int MRD_RDS_AF_ON = 0x31;
	public static final int MRD_RDS_TA_OFF = 0x32;
	public static final int MRD_RDS_TA_ON = 0x33;
	public static final int MRD_RDS_EON_OFF = 0x34;
	public static final int MRD_RDS_EON_ON = 0x35;
	public static final int MRD_RDS_REG_OFF = 0x36;
	public static final int MRD_RDS_REG_ON = 0x37;
	public static final int MRD_RDS_PTY_OFF = 0x38;
	public static final int MRD_RDS_PTY_ON = 0x39;
	public static final int MRD_RDS_PTY_TYPE = 0x3a;
	public static final int MRD_RDS_PTY_SEEK_UP = 0x3b;
	public static final int MRD_RDS_PTY_SEEK_DOWN = 0x3c;
	public static final int MRD_RDS_INFO = 0x3f;
	public static final int MRD_RDS_READ_FREQ_RANGE = 0x40;
	public static final int MRD_OPEN = 0x80;
	public static final int MRD_CLOSE = 0xff;

	public static final int MRD_INFO_BAND = 0x00000001;
	public static final int MRD_INFO_NUMBER = 0x00000002;
	public static final int MRD_INFO_FREQENCY = 0x00000004;
	public static final int MRD_INFO_STRENGTH = 0x00000008;
	public static final int MRD_INFO_FLAG = 0x00000010;
	public static final int MRD_INFO_FREQS = 0x00000020;
	public static final int MRD_INFO_REGION = 0x00000040;
	public static final int MRD_INFO_PARAM = 0x00000080;
	public static final int MRD_INFO_PS = 0x00040000;
	public static final int MRD_INFO_LOCDX = 0x00080000;
	public static final int MRD_INFO_STEREOMONO = 0x00100000;
	public static final int MRD_INFO_SCAN = 0x00200000;
	public static final int MRD_INFO_AS = 0x00400000;
	public static final int MRD_INFO_SEEK = 0x00800000;
	public static final int MRD_INFO_FREQ_RANGE = 0x01000000;


	public static final int MRD_INFO_FLAG_PS = 0x04;
	public static final int MRD_INFO_FLAG_LOCDX = 0x08;
	public static final int MRD_INFO_FLAG_STEREOMONO = 0x10;
	public static final int MRD_INFO_FLAG_SCAN = 0x20;
	public static final int MRD_INFO_FLAG_AS = 0x40;
	public static final int MRD_INFO_FLAG_SEEK = 0x80;
	
	public static final int MRD_RDS_FLAG = 0x00000200;
	public static final int MRD_RDS_PTY = 0x00000400;
	public static final int MRD_RDS_PS = 0x00000800;
	public static final int MRD_RDS_RT = 0x00001000;
	public static final int MRD_RDS_PSLIST = 0x00002000;
	public static final int MRD_RDS_DEBUG_INFO = 0x00008000;
	public static final int MRD_RDS_TA = 0x02000000;
	public static final int MRD_RDS_REG_SW = 0x040000000;
	public static final int MRD_RDS_EON_SW = 0x08000000;
	public static final int MRD_RDS_PTY_SW = 0x10000000;
	public static final int MRD_RDS_TA_SW = 0x20000000;
	public static final int MRD_RDS_AF_SW = 0x40000000;
	public static final int MRD_RDS_TP = 0x80000000;

	public static final int MRD_RDS_FLAG_TA = 0x02;
	public static final int MRD_RDS_FLAG_REG_SW = 0x04;
	public static final int MRD_RDS_FLAG_EON_SW = 0x08;
	public static final int MRD_RDS_FLAG_PTY_SW = 0x10;
	public static final int MRD_RDS_FLAG_TA_SW = 0x20;
	public static final int MRD_RDS_FLAG_AF_SW = 0x40;
	public static final int MRD_RDS_FLAG_TP = 0x80;

	public static final int MRD_READ_DEBUG_INFO = 0xf0;
	public static final int MRD_READ_RDS_DEBUG_INFO = 0xf1;

	private native final int nativeSendMRDCommand(int value);

	public int sendMRDCommand(int value) {
		return nativeSendMRDCommand(value);
	}

	private IMRDCallback mMRDCallback;

	private void mrdCallback(int value) {
		if (mMRDCallback != null) {
			mMRDCallback.mrdCallback(value);
		}
	}

	public void setMRDCallback(IMRDCallback mrdCallback) {
		mMRDCallback = mrdCallback;
	}
	

	private int mMRDMask = 0xffffffff;

	public void setMRDMask(int value) {
		if (value == 0) {
			value = 0xffffffff;
		}
		mMRDMask = value;
	}

	public static final int MY_KEY_BAUD = 0x1;
	public static final int MY_BIND_SERVICE_FINISH = 0x2;
	
	public static final int MY_KEY_AS = 0x5;
	public static final int MY_KEY_NUM1 = 0x6;
	public static final int MY_KEY_NUM2 = 0x7;
	public static final int MY_KEY_NUM3 = 0x8;
	public static final int MY_KEY_NUM4 = 0x9;
	public static final int MY_KEY_NUM5 = 0xa;
	public static final int MY_KEY_NUM6 = 0xb;


	public static final int MY_KEY_LONG_NUM1 = 0x16;
	public static final int MY_KEY_LONG_NUM2 = 0x17;
	public static final int MY_KEY_LONG_NUM3 = 0x18;
	public static final int MY_KEY_LONG_NUM4 = 0x19;
	public static final int MY_KEY_LONG_NUM5 = 0x1a;
	public static final int MY_KEY_LONG_NUM6 = 0x1b;
	
	private IMSCCallback mMYCallback;

	private void myCallback(int value) {
		if (mMYCallback != null) {
			mMYCallback.mscCallback(value);
		}
	}
	
	public void setMYCallback(IMSCCallback myCallback) {
		mMYCallback = myCallback;
	}
	public byte mMRDBand;
	public byte mMRDNumber;
	public short mMRDFreqency;
	public byte mMRDStrength;
	public byte mMRDFlag;
	public short[] mMRDFreqs = new short[12];
	public byte mMRDRegion;
	public byte[] mMRDParam = new byte[4];
	
	public byte mMRDRdsFlag;
	public byte[] mMRDRdsPty = new byte [2];
	public byte[] mMRDRdsPs = new byte [8];
	public byte[] mMRDRdsRt = new byte [64];
	public byte[][] mMRDRdsPslist = new byte [12][8];
	public byte[] mMRDRdsDinfo = new byte [32];
	public byte mMRDRdsPtyType;
	public short mFreqMax;
	public short mFreqMin;
	// ////////////////////////////////
	private MYServiceConnection mConnection = new MYServiceConnection();
	public IMyService mIMYService;

	public boolean bindMYService(Context c) {
		if (mIMYService == null) {
			Intent intent = new Intent();
    		intent.setClassName("com.my.out",
    				"com.my.service.MyService");

			return c.bindService(intent, mConnection, 0);
		}
		return true;
	}

    public void unbindMYService(Context c){
    	if (mIMYService != null) {
    		try {
				mIMYService.commonUnregisterCallback(mCallback);
			} catch (RemoteException e) {
				Log.e(TAG, " " + e.getMessage());
			}
			
			mIMYService = null;
			c.unbindService(mConnection);  
		} 	  
    }

    public void reportCanboxPlayStatus(){
//		if (mIMYService != null) {
//			try{
//				mIMYService.canboxReportPlayStatus(MyCmd.SOURCE_RADIO, (int)mMRDFreqency, 0, mMRDBand, (byte)0);
//			} catch (RemoteException e) {
//				Log.e(TAG, "" + e.getMessage());
//			}
//			
//		}
	}
    
	public void notifyMYAppForeground() {
		if (mIMYService != null) {
			try{
				mIMYService.setAppForeground(MyCmd.SOURCE_RADIO);
			} catch (RemoteException e) {
				Log.e(TAG, "" + e.getMessage());
			}
			
		}
	}

	public void notifyMYAppBackground() {
		if (mIMYService != null) {
			try{
				mIMYService.setAppBackground(MyCmd.SOURCE_RADIO);
			} catch (RemoteException e) {
				Log.e(TAG, "" + e.getMessage());
			}
			
		}
	}
	
	private final Handler mHandlerForCommonCallback = new Handler(){
		public void handleMessage(Message msg) {
			int result = msg.what;			
			if (mMRDCallback != null) {
				switch (result){
				case MyCmd.CALLBACK_COMMON_KEY_BAUD:
					result = MY_KEY_BAUD;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_AS:
					result = MY_KEY_AS;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM1:
					result = MY_KEY_NUM1;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM2:
					result = MY_KEY_NUM2;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM3:
					result = MY_KEY_NUM3;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM4:
					result = MY_KEY_NUM4;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM5:
					result = MY_KEY_NUM5;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_NUM6:
					result = MY_KEY_NUM6;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM1:
					result = MY_KEY_LONG_NUM1;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM2:
					result = MY_KEY_LONG_NUM2;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM3:
					result = MY_KEY_LONG_NUM3;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM4:
					result = MY_KEY_LONG_NUM4;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM5:
					result = MY_KEY_LONG_NUM5;
					break;
				case MyCmd.CALLBACK_COMMON_KEY_LONG_NUM6:
					result = MY_KEY_NUM6;
					break;
				default:
					result = 0;
				}
				if (result != 0) {
					myCallback(result);
				}
			}
			super.handleMessage(msg);
		}		
	};
	
	private ICallback.Stub mCallback = new ICallback.Stub() {
        public void callback(int result, int param1, int param2, String str) {
        	mHandlerForCommonCallback.sendEmptyMessage(result); //only use result now.
        }
    };

	
	private class MYServiceConnection implements ServiceConnection {
		public void onServiceConnected(ComponentName name, IBinder service) {

			if (mIMYService == null) {
				mIMYService = IMyService.Stub.asInterface(service);
			}
			
			try {
				mIMYService.commonRegisterCallback(mCallback);
			} catch (RemoteException e) {
				Log.e(TAG, " " + e.getMessage());
			}
			myCallback(MY_BIND_SERVICE_FINISH);
		}

		public void onServiceDisconnected(ComponentName name) {
			/*
			 * sdk This is called when the connection with the service has been
			 * unexpectedly disconnected -- that is, its process crashed.
			 * Because it is running in our same process, we should never see
			 * this happen.
			 */
		}
	}
	
	///
	public static int mFreqListSize = 12;
	public static boolean isRds(){
		return false;
	}

}
